﻿using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

[InitializeOnLoad]
public class ExecutionOrderEditor
{
    private const string PB_TITLE = "更新执行顺序";
    private const string ERR_MESSAGE = "找不到{0}脚本";

    [InitializeOnLoadMethod]
	public static void Run()
	{
		var type = typeof(ExecutionOrderAttribute);
		var assembly = type.Assembly;
		var types = assembly.GetTypes();
		var scripts = new Dictionary<MonoScript, ExecutionOrderAttribute>();

		var progress = 0f;
		var step = 1f / types.Length;
        
        foreach (var item in types)
        {
            var attributes = item.GetCustomAttributes(type, false);

            if (attributes.Length != 1)
                continue;

            var attribute = attributes[0] as ExecutionOrderAttribute;
            
            var asset = "";

            //从Asset中拿到这个脚本的唯一标识符(就是哪个guid特性里面的值)
            var guids = AssetDatabase.FindAssets(string.Format("{0} t:script", item.Name));

            if (guids.Length > 1)
            {
                foreach (var guid in guids)
                {
                    var assetPath = AssetDatabase.GUIDToAssetPath(guid);
                    var filename = Path.GetFileNameWithoutExtension(assetPath);
                    if (filename == item.Name)
                    {
                        asset = guid;
                        break;
                    }
                }
            }
            else if (guids.Length == 1)
            {
                asset = guids[0];
            }
            else
            {
                Debug.LogErrorFormat(ERR_MESSAGE, item.Name);
                return;
            }

            MonoScript script = AssetDatabase.LoadAssetAtPath<MonoScript>(AssetDatabase.GUIDToAssetPath(asset));

            scripts.Add(script, attribute);
        }

        bool changed = false;
        foreach (var item in scripts)
        {
            if (MonoImporter.GetExecutionOrder(item.Key) != item.Value.ExecutionOrder)
            {
                changed = true;
                break;
            }
        }

        if (changed)
        {
            foreach (var item in scripts)
            {
                var cancelled = EditorUtility.DisplayCancelableProgressBar(PB_TITLE, string.Format("设置{0}顺序",item.Key.name), progress);
                progress += step;
                if (MonoImporter.GetExecutionOrder(item.Key) != item.Value.ExecutionOrder)
                {
                    MonoImporter.SetExecutionOrder(item.Key, item.Value.ExecutionOrder);
                }
                
                if (cancelled) break;
            }
            Debug.Log("排序行为执行");
        }


        EditorUtility.ClearProgressBar();
    }
}
